/*
 * [y] hybris Platform
 *
 * Copyright (c) 2000-2016 SAP SE
 * All rights reserved.
 *
 * This software is the confidential and proprietary information of SAP
 * Hybris ("Confidential Information"). You shall not disclose such
 * Confidential Information and shall use it only in accordance with the
 * terms of the license agreement you entered into with SAP Hybris.
 */
package acc.asset.sync.setup;

import static acc.asset.sync.constants.AccAssetSyncDemoConstants.PLATFORM_LOGO_CODE;

import de.hybris.platform.core.initialization.SystemSetup;
import de.hybris.platform.scripting.enums.ScriptType;
import de.hybris.platform.scripting.model.ScriptModel;
import de.hybris.platform.servicelayer.impex.ImportConfig;
import de.hybris.platform.servicelayer.impex.ImportResult;
import de.hybris.platform.servicelayer.impex.ImportService;
import de.hybris.platform.servicelayer.impex.impl.StreamBasedImpExResource;
import de.hybris.platform.servicelayer.model.ModelService;

import java.io.InputStream;

import org.apache.log4j.Logger;

import acc.asset.sync.constants.AccAssetSyncDemoConstants;
import acc.asset.sync.service.AccAssetSyncDemoService;


@SystemSetup(extension = AccAssetSyncDemoConstants.EXTENSIONNAME)
public class AccAssetSyncDemoSystemSetup
{
	private final static Logger LOG = Logger.getLogger(AccAssetSyncDemoSystemSetup.class);

	private static final String SYNC_SCRIPT = "import de.hybris.platform.servicelayer.search.FlexibleSearchQuery\n"
			+ "import de.hybris.y2ysync.services.SyncExecutionService.ExecutionMode\n" + "\n" + "def syncJob = findJob '%s'\n"
			+ "syncExecutionService.startSync(syncJob, ExecutionMode.SYNC)\n" + "\n" + "def findJob(code) {\n"
			+ "\tdef fQuery = new FlexibleSearchQuery('SELECT {PK} FROM {Y2YSyncJob} WHERE {code}=?code')\n"
			+ "\tfQuery.addQueryParameter('code', code)\n" + "\n" + "\tflexibleSearchService.searchUnique(fQuery)\n" + "}";
	private static final String REMOVE_VERSION_MARKERS_SCRIPT = "import de.hybris.platform.servicelayer.search.FlexibleSearchQuery\n"
			+ "\n" + "def fQuery = new FlexibleSearchQuery('SELECT {PK} FROM {ItemVersionMarker}')\n"
			+ "def result = flexibleSearchService.search(fQuery)\n" + "\n" + "result.getResult().forEach {\n"
			+ "modelService.remove(it) \n" + "}";
	private static final String UPLOAD_DH_EXTENSION_SCRIPT = "import com.hybris.datahub.client.extension.ExtensionInputStreamSource\n"
			+ "\n" + "def inp = getClass().getResourceAsStream('/y2ysync-demo-dh-model.xml')\n"
			+ "def source = new ExtensionInputStreamSource(inp)\n" + "\n" + "dataHubExtensionUploadService.uploadExtension(source)";


	private final AccAssetSyncDemoService accAssetSyncDemoService;
	private final ModelService modelService;
	private final ImportService importService;

	public AccAssetSyncDemoSystemSetup(final AccAssetSyncDemoService accAssetSyncDemoService, final ModelService modelService,
			final ImportService importService)
	{
		this.accAssetSyncDemoService = accAssetSyncDemoService;
		this.modelService = modelService;
		this.importService = importService;
	}

	@SystemSetup(process = SystemSetup.Process.INIT, type = SystemSetup.Type.ESSENTIAL)
	public void createEssentialData()
	{
		accAssetSyncDemoService.createLogo(PLATFORM_LOGO_CODE);

		impexImport("/impex/projectdata-streams.impex");
		createScript("uploadDhExtension", UPLOAD_DH_EXTENSION_SCRIPT);
	}

	@SystemSetup(type = SystemSetup.Type.PROJECT)
	public boolean addProjectData()
	{
		LOG.info("Starting custom project data loading for the accAssetSyncDemo extension");
		impexImport("/impex/projectdata-streams.impex");
		LOG.info("Custom project data loading for the accAssetSyncDemo extension completed.");
		return true;
	}

	protected boolean impexImport(final String filename)
	{
		final String message = "accAssetSyncDemo impexing [" + filename + "]...";
		try
		{
			LOG.info(message);
			final InputStream resourceAsStream = getClass().getResourceAsStream(filename);
			final ImportConfig importConfig = new ImportConfig();
			importConfig.setScript(new StreamBasedImpExResource(resourceAsStream, "UTF-8"));
			importConfig.setLegacyMode(Boolean.FALSE);
			final ImportResult importResult = this.importService.importData(importConfig);
			if (importResult.isError())
			{
				LOG.error(message + " FAILED");
				return false;
			}
		}
		catch (final Exception e)
		{
			LOG.error(message + " FAILED", e);
			return false;
		}
		return true;
	}

	private InputStream getImageStream()
	{
		return AccAssetSyncDemoSystemSetup.class.getResourceAsStream("/accAssetSyncDemo/sap-hybris-platform.png");
	}

	private String getSyncScriptContent(final String cronJobCode)
	{
		return String.format(SYNC_SCRIPT, cronJobCode);
	}

	private void createScript(final String code, final String content)
	{
		final ScriptModel script = modelService.create(ScriptModel.class);
		script.setScriptType(ScriptType.GROOVY);
		script.setContent(content);
		script.setCode(code);
		modelService.save(script);
	}

}
